import weka.clusterers.SimpleKMeans;
import weka.core.Instances;
import weka.core.converters.ConverterUtils.DataSource;
import weka.filters.Filter;
import weka.filters.unsupervised.attribute.Standardize;
import weka.filters.unsupervised.attribute.PrincipalComponents;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import java.io.File;
import java.io.IOException;

public class 聚类分析 {

    public static void main(String[] args) throws Exception {
        // 读取CSV文件
        DataSource dataSource = new DataSource("D:\\Marketing Campaign\\填充后的数据集.csv");
        Instances data = dataSource.getDataSet();
        data.setClassIndex(data.numAttributes() - 1); // 设置最后一列为类别属性（如果有的话）

        // 选择特征
        String[] features = {"MntWines", "MntFruits", "MntMeatProducts", "MntFishProducts", "MntSweetProducts", "MntGoldProds"};
        Instances selectedData = selectFeatures(data, features);

        // 选择K值
        int k = 6;

        // 应用K-means算法
        SimpleKMeans kmeans = new SimpleKMeans();
        kmeans.setNumClusters(k);
        kmeans.setSeed(0);
        kmeans.buildClusterer(selectedData);

        // 将聚类结果添加到原始数据集
        Instances clusteredData = new Instances(selectedData);
        for (int i = 0; i < clusteredData.numInstances(); i++) {
            clusteredData.instance(i).setValue(clusteredData.numAttributes() - 1, kmeans.clusterInstance(clusteredData.instance(i)));
        }

        // 使用PCA将数据降维到二维
        PrincipalComponents pca = new PrincipalComponents();
        pca.setMaximumAttributesToSelect(2);
        pca.setInputFormat(clusteredData);
        Instances pcaData = Filter.useFilter(clusteredData, pca);

        // 绘制聚类结果
        XYSeriesCollection dataset = new XYSeriesCollection();
        for (int i = 0; i < k; i++) {
            XYSeries series = new XYSeries("Cluster " + i);
            for (int j = 0; j < pcaData.numInstances(); j++) {
                if (pcaData.instance(j).value(pcaData.numAttributes() - 1) == i) {
                    series.add(pcaData.instance(j).value(0), pcaData.instance(j).value(1));
                }
            }
            dataset.addSeries(series);
        }

        JFreeChart chart = ChartFactory.createScatterPlot(
                "K-means Clustering Result",
                "Principal Component 1",
                "Principal Component 2",
                dataset,
                PlotOrientation.VERTICAL,
                true, true, false);

        ChartFrame frame = new ChartFrame("K-means Clustering with PCA", chart);
        frame.pack();
        frame.setVisible(true);
    }

    private static Instances selectFeatures(Instances data, String[] features) throws IOException {
        Instances selectedData = new Instances(data, 0);
        for (String feature : features) {
            int index = data.attribute(feature).index();
            selectedData.insertAttributeAt(index, data.attribute(feature));
        }
        for (int i = 0; i < data.numInstances(); i++) {
            selectedData.add(data.instance(i));
        }
        return selectedData;
    }
}